A project to add some more control to the PS5 Kerbal simulation.

Starting point

After installing Kerbal on the PS5 and playing it for a while it quickly became clear that the controllers alone are not enough to enjoy the game. The search began to find some way of improving things. Kerbal allows control vi the PS5 controllers AND via keyboard and mouse. This means it should be possible to add some easy toggles/switches/rotary encoders to pass information to the game. The first switch would be the space bar which kerbal uses to trigger stages.

kerbal key bindings

The following is a list of key bindings we can work with.

Arduino - pro micro (5V)

Initial choice for a prototype is the AVR ATmega32u4 8-bit microcontroller which has a USB controller and can therefore be used as both a keyboard and mouse if required.

The Pro Micro is an Arduino-compatible microcontroller board developed under an open hardware license by Sparkfun. Clones of the Pro Micro are often used as a lower-cost alternative to a Teensy 2.0 as a basis for a DIY keyboard controller/converter when a lower number of pins would suffice.

WS2812 LEDs

Because it’s always good to have status LEDs an the WS2812 is one that is both easy to get and has good libraries with fastled and adafruit.

The fastled library looks like a good choice although it doesn’t (yet) support RGBW LEDs for which I have a LED ring. The other LED rings I have are less tightly packed with LEDs. As I have a few WS2812 strips on top of the one RGBW ring the choice went towards the WS2812 to be able to mix the strip and ring. RGBW is better suited to lighting anyway so let’s use it for that later.

Step 1 - First prototype

To get started I went to an example for LEDs to be able to later set a LED with a key/button.

First LED example (arduino IDE)
#include <FastLED.h>
#define NUM_LEDS 22
#define NUM_RING_LEDS 12
#define DATA_PIN 7

CRGB leds[NUM_LEDS];

void setup() { 
    FastLED.addLeds<NEOPIXEL, DATA_PIN>(leds, NUM_LEDS);
    leds[12] = CHSV(0, 255, 16);
    leds[13] = CHSV(33, 255, 16);
    leds[14] = CHSV(65, 255, 16);
    leds[15] = CHSV(97, 255, 16);
    leds[16] = CHSV(129, 255, 16);
    leds[17] = CHSV(161, 255, 16);
    leds[18] = CHSV(193, 255, 16);
    leds[19] = CHSV(225, 255, 16);
    leds[20] = CHSV(255, 255, 16);
    leds[21] = CHSV(255, 255, 16);
    FastLED.show();
}

void loop() {
    for(int dot = 0; dot < NUM_RING_LEDS; dot++) { 
        leds[dot] = CHSV(64, 255, 16);
        FastLED.show();
        // clear this led for the next time around the loop
        leds[dot] = CRGB::Black;
        delay(150);
    }
}

The first test looks good.

Prototype led ring and strip
Figure 1. Initial breadboard prototype with WS2812 ring and strip

The above code runs a LED around the ring and sets static colours on the strip. A good start.

Step 2 - Attach a button to trigger a stage

Since this will be starting rockets let’s make it feel that way. Just the space bar and maybe a toggle to arm it.

Button Triger stage
Figure 2. first buttons

The big red button is to trigger a stage and the toggle switch is to arm it.

Let’s see if that works.

initial tests
const int ARMPin = 2;     // the number of the pushbutton pin
const int StagePin = 3;     // the number of the pushbutton pin
const int ledPin =  13;      // the number of the LED pin

int ARMState = 0;         // variable for reading the pushbutton status
int Armed = 0;         // variable to set when armed


void setup() {
    // initialize the LED pin as an output:
    pinMode(ledPin, OUTPUT);
    // initialize the pushbutton pin as an input:
    pinMode(ARMPin, INPUT);
    pinMode(StagePin, INPUT);
}

void loop() {
    // read the state of the pushbutton value:
    ARMState = digitalRead(ARMPin);

    // check if the pushbutton is pressed. If it is, the ARMState is HIGH:
    if (ARMState == HIGH) {
        // turn LED on:
        digitalWrite(ledPin, HIGH);
        Armed = 1;
    } else {
        // turn LED off:
        digitalWrite(ledPin, LOW);
        Armed = 0;
    }
}

Step 3 - rotary encoders

Appendix A: Requirements

Initial list of requirements
  • Control Kerbal on PS5

    • Via USB(A) keyboard interface

      • Use big red button with latch for stages

    • Must show actions/button presses

      • WS2812 for key status changes red/green/etc

    • Add some safety toggles (arm/disarm)

      • A classic toggle with red cover

    • Control

      • Stage trigger (space bar)

      • SAS (on/off) (t)

      • gear (up/down) (g)

      • time warp (rotary +/-) (.,)

      • throttle (rotary +/-) (shift,cntrl)

      • motors (on/off) (x,k)

      • View (inside/outside) ???

This should cover the most required buttons and should be possible without multiplexing.

Appendix B: Interface design thoughts

Since the first button is a big red one with a latch it make sense to also show what state it’s in. Adding a LED ring around it sounds like a good idea. Adding a LED ring around a rotary encoder also sounds like a good idea (optional).

Arm/disarm toggle

toggle disarmed

Arm led LED green(?), latch ring red blink(?)

toggle armed

ARM led red, latch ring green

Triger stage button

unlatched

ring green

press

ring red for 1 sec

latched

Ring orange